﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using NUnit.Framework;
using Contoso.Models;
using Contoso.Tests.Helpers;
using Contoso.Controllers;
using Contoso.Helpers;

namespace Contoso.Tests.Controllers
{
    [TestFixture]
    public class StudentControllerTest
    {
        private static List<Student> testData = Fakes.FakeStudentsData.CreateStudentData();
        private IUnitOfWork unitOfWork = UnitTestHelpers.MockUnitOfWork(testData);

        StudentController CreateStudentController()
        {
            var testData = Fakes.FakeStudentsData.CreateStudentData();

            var unitofwork = unitOfWork;

            return new StudentController(unitofwork);
        }

        StudentController CreateStudentControllerAs(string userName)
        {
            var mock = new Moq.Mock<ControllerContext>();
            mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
            mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

            var controller = CreateStudentController();
            controller.ControllerContext = mock.Object;

            return controller;
        }






        [Test]
        public void Index_Should_Return_View()
        {
            // Arrange
            var controller = new StudentController(unitOfWork);

            // Act
            var result = controller.Index();

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }


        [Test]
        public void Index_Should_Return_Typed_View_Of_List_Students()
        {
            // Arrange
            var controller = new StudentController(unitOfWork);

            // Act
            var result = (ViewResult)controller.Index();

            // Assert
            Assert.IsInstanceOf(typeof(IQueryable<Student>), result.ViewData.Model, "Index does not have an IQueryable<Student> as its model");
        }



        [Test]
        public void Details_Should_Return_View()
        {
            // Arrange
            var controller = new StudentController(unitOfWork);

            // Act 
            var result = controller.Details(1);

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }

        [Test]
        public void Details_Should_Return_Typed_View_Of_Type_Student()
        {
            // Arramge 
            var controller = new StudentController(unitOfWork);

            // Act
            var result = (ViewResult)controller.Details(1);

            // Assert
            Assert.IsInstanceOf(typeof(Student), result.ViewData.Model, "Details should return a Student as its model");
        }

        [Test]
        public void Details_Should_Return_FileNotFound_For_Invalid_StudentID_Supplied()
        {
            // Arrange
            var controller = new StudentController(unitOfWork);

            // Act
            var result = controller.Details(null);

            // Assert
            Assert.IsInstanceOf(typeof(FileNotFoundResult), result);
            Assert.AreEqual("Invalid StudentID supplied", ((FileNotFoundResult)result).Message);
        }

        [Test]
        public void Details_Should_Return_FileNotFound_For_Bogus_Student()
        {
            // Arrange
            var controller = new StudentController(unitOfWork);

            // Act
            var result = controller.Details(777);

            // Assert
            Assert.IsInstanceOf(typeof(FileNotFoundResult), result);
            Assert.AreEqual("No Student found for that StudentID supplied", ((FileNotFoundResult)result).Message);
        }


        [Test]
        public void Create_HttpGet_Should_Return_ViewResult()
        {
            // Arrange
            var controller = new StudentController(unitOfWork);

            // Act
            var result = controller.Create();

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }


        [Test]
        public void Create_HttpPost_Should_Save_New_Student()
        {
            // Arrange
            var studentsCount = unitOfWork.StudentsRepository.Students().Count();
            var controller = new StudentController(unitOfWork);
            var student = Fakes.FakeStudentsData.CreateStudent();

            // Act
            var result = controller.Create(student);

            // Assert
            Assert.AreEqual(studentsCount+1, unitOfWork.StudentsRepository.Students().Count());
            Assert.IsInstanceOf(typeof(RedirectToRouteResult), result);
        }





        //[Test]
        //public void Create_HttpPost_Should_Save_New_Student()
        //{
        //    // Arrange
        //    var controller = new StudentController(unitOfWork);
        //    var form = Fakes.FakeStudentsData.CreateStudentsFormCollection();
        //    controller.ValueProvider = form.ToValueProvider();

        //    // Act
        //    var result = controller.Create(form);

        //    // Assert
        //    Assert.AreEqual(9, unitOfWork.StudentsRepository.Students().Count());
        //    Assert.IsInstanceOf(typeof(RedirectToRouteResult), result);
        //}
    }
}
